<template>
  <div class="flex-row">
    <slot name="search"></slot>
    <a-button type="primary" v-if="showQuery" @click="getData" style="margin-right:10px;">查询</a-button>
    <a-button type="primary" v-if="showAdd" style="margin-right:10px;"
              @click="showSave=true;$emit('update:saveFormData',{})">新增
    </a-button>
    <a-button type="danger" v-if="rowSelection.selectedRowKeys.length" @click="batchDelete" style="margin-right:10px;">删除</a-button>
    <slot name="searchBar"></slot>
  </div>

  <a-table :scroll="{x:'min-content'}" :columns="tableColumns" :data-source="tableData" :pagination="pagination" @change="tableChange" :row-selection="rowSelection">
    <template #bodyCell="{ column,record  }">
      <template v-if="column.key === 'action'">
        <a-popconfirm
            v-if="showDelete(record)"
            title="确定删除此数据吗？"
            ok-text="删除"
            cancel-text="取消"
            okType="danger"
            @confirm="deleteRow(record)"
        >
          <a-button type="primary" size="small" danger class="ml-10">删除</a-button>
        </a-popconfirm>

        <a-button @click="$emit('update:saveFormData',record);showSave=true" v-if="showEdit" type="primary"
                  size="small"
                  class="ml-10">{{ editTexT }}
        </a-button>
        <slot name="actionBar" :record="record" :column="column"></slot>
      </template>
      <template v-if="record[column.key]&&column.key.endsWith('_time')">
        {{ formatTime(record[column.key]) }}
      </template>
      <template v-if="record[column.key]&&column.key.endsWith('_img')">
        <a-image
            :width="40"
            :src="baseURL+'/'+record[column.key]"
        />
      </template>
      <template v-if="column.key.startsWith('is_')">
        {{ record[column.key] === 1 ? '是' : '否' }}
      </template>
      <template v-if="column.render">
        {{ column.render(record) }}
      </template>
    </template>
    <template #headerCell="{ column }">
      <template v-if="column.key === 'action'">
        <div class="justify-end align-center">
          <a-tooltip title="导出表格">
            <FileExcelOutlined class="mr-10" @click="exports"/>
          </a-tooltip>
          <span>{{ column.title }}</span>
        </div>
      </template>
    </template>
  </a-table>

  <a-modal :footer="null" v-model:visible="showSave" :width="modelWidth"
           :title="saveFormData&&saveFormData[`${table_key}`]?editTexT:'新增'"
           @cancel="showSave=null">
    <slot name="save"></slot>

    <div class="justify-end">
      <a-button type="default" @click.prevent="showSave=false;$emit('update:saveFormData',{});"
                style="margin-right: 10px">取消
      </a-button>
      <a-button type="primary" html-type="submit" @click="submit">提交</a-button>
    </div>
  </a-modal>
</template>

<script lang="jsx">
import * as ExcelJS from "exceljs";
import {defineAsyncComponent} from "vue";
import {saveAs} from 'file-saver';

export default {
  name: "crud",
  data: function () {
    return {
      showSave: false,
      tableData: [],
      tableColumns: [],
      pagination: {
        current: 1,
        total: null,
        pageSize: 13,
        showTotal: (total, range) => `当前:${range[0]}-${range[1]}  共:${total} 条`,
        showSizeChanger: true,
        showQuickJumper: true,
      },
      rowSelection: {
        selectedRowKeys:[],
        onChange:(e)=>{
          this.rowSelection.selectedRowKeys = e;
          this.$emit('rowSelectionChange',e)
        }
      },
    };
  },
  computed: {
    table_key() {
      return `${this.table}_id`
    },
  },
  props: {
    showDelete: {
      type: Function,
      default: () => () => {
        return true
      }
    },
    showEdit: {
      type: Boolean,
      default: true
    },
    pageSize: {
      type: Number,
      default: 13
    },
    save_form: {
      type: Object,
      default: null
    },
    showAdd: {
      type: Boolean,
      default: true
    },
    showQuery: {
      type: Boolean,
      default: true
    },
    editTexT: {
      type: String,
      default: '编辑'
    },
    table: {
      type: String,
      required: true
    },
    join_table: {
      type: String,
      default: null
    },
    columns: {
      type: Array,
      required: true
    },
    saveFormData: {
      type: Object,
      default: () => {
      }
    },
    searchObj: {
      type: Object,
      default: () => {
      }
    },
    deleteFunc: {
      type: Function,
      default: null
    },
    listFunc: {
      type: Function,
      default: null
    },
    saveFunc: {
      type: Function,
      default: null
    },
    modelWidth: {
      type: Number,
      default: 600
    },
  },
  watch: {
    columns: {
      handler(newV, oldV) {
        let tableColumns = [{
          title: 'ID',
          key: `${this.table_key}`,
        }, ...newV, {
          title: '操作',
          key: 'action',
          align: 'right',
        }].map(i => {
          i.align = i.align ? i.align : 'center'
          i.dataIndex = i.dataIndex ? i.dataIndex : i.key
          i.render = i.render ? i.render : null
          i.ellipsis = i.ellipsis ? i.ellipsis : false
          i.customRender = i.customRender ? i.customRender : null
          return i
        })
        this.tableColumns = tableColumns
        // console.log(111, newV, this.tableColumns)
      },
      immediate: true,
      deep: true,
    },
    pageSize: {
      handler(newV, oldV) {
        this.pagination.pageSize = newV;
      },
      immediate: false,
    },
  },
  components: {
    FileExcelOutlined: defineAsyncComponent(() => import('@ant-design/icons-vue/FileExcelOutlined'))
  },
  created() {
    this.getData()
  },
  methods: {
    jsx(){


    },
    batchDelete(){
      this.get('/admin/crud/batchDelete', {table: this.table, table_ids: this.rowSelection.selectedRowKeys }).then(({code}) => {
        if (code === 1) {
          this.success('批量删除成功！');
          this.getData()
        }
      })
    },
    tableChange(pagination, filters, sorter, {currentDataSource}) {
      this.pagination = {...this.pagination, ...pagination};
      this.getData()
    },
    async exports() {
      const workbook = new ExcelJS.Workbook();
      workbook.creator = '计算客软件';
      workbook.lastModifiedBy = '计算客软件';
      workbook.created = new Date();
      workbook.modified = new Date();
      workbook.lastPrinted = new Date();
      const sheet = workbook.addWorksheet('My Sheet');

      sheet.columns = this.tableColumns.filter(i => i.key != 'action').map(i => {
        return {
          header: i.title, key: i.key, width: i.title.length * 3
        }
      });
      const data = this.tableData.map(i => {
        return i
      });

      sheet.addRows(data);
      let fileName = window.location.href
      workbook.xlsx.writeBuffer().then(function (buffer) {
        // console.log(666, buffer)
        saveAs(
            new Blob([buffer], {type: "application/octet-stream"}),
            `${fileName}.xlsx`
        );
      });
    },
    deleteRow(row) {
      if (this.deleteFunc) {
        this.deleteFunc(row);
        return;
      }
      this.get('/admin/crud/delete', {table: this.table, table_id: row[this.table_key]}).then(({code}) => {
        if (code === 1) {
          this.success('删除成功！');
          this.getData()
        }
      })
    },
    submit() {
      if(this.$parent.$refs.save_form){
        this.$parent.$refs.save_form.validate().then((e) => {
          this.submitPost();
        }).catch(err => {
          console.log('error', err);
          this.error(err.errorFields[0].errors[0]||'数据校验失败！')
        });
      }else{
        this.submitPost();
      }
    },
    submitPost(){
      if (this.saveFunc) {
        this.saveFunc(this.saveFormData);
        return;
      }
      this.post('/admin/crud/save', {table: this.table, ...this.saveFormData}).then(({code}) => {
        if (code === 1) {
          this.getData()
          this.showSave = false
          this.success('保存成功！');
        }
        this.$emit('update:saveFormData', {})
      })
    },
    async getData() {
      let param = {
        page: this.pagination.current,
        limit: this.pagination.pageSize,
        table: this.table,
        join_table: this.join_table,
        ...this.searchObj,
      }
      let code = null, paginate = null
      if (this.listFunc) {
        ({code, paginate} = await this.listFunc(param))
      } else {
        ({code, paginate} = await this.get('/admin/crud/list', param))
      }
      if (code === 1) {
        this.tableData = paginate.data.map(i=>{
          return {
            ...i,
            key:i[this.table_key]
          }
        })
        this.pagination = {...this.pagination,
          current: paginate.current_page,
          total: paginate.total,
          pageSize: paginate.per_page,
        }
      }
    },
  }
}
</script>
<style scoped lang="less">
</style>